package com.bestcem.xm.qdes.controller.v3;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bestcem.xm.common.core.annotation.XmGet;
import com.bestcem.xm.common.core.constant.ReqErrorCodeConstants;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import com.bestcem.xm.qdes.controller.param.*;
import com.bestcem.xm.qdes.controller.vo.*;
import com.bestcem.xm.qdes.entity.QdesProject;
import com.bestcem.xm.qdes.entity.QdesProjectEntry;
import com.bestcem.xm.qdes.service.QdesLibProjectService;
import com.bestcem.xm.qdes.service.QdesProjectEntryService;
import com.bestcem.xm.qdes.service.QdesProjectService;
import com.bestcem.xm.qdes.service.QdesQuestionLibService;
import com.bestcem.xm.qdes.util.PageUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Api(tags = "问卷编辑-V3")
@RestController
@RequiredArgsConstructor
@RequestMapping("/qdes/v3/projects")
public class ProjectV3Controller {

    private @NonNull QdesQuestionLibService questionlibService;
    private @NonNull QdesProjectService projectService;
    private @NonNull QdesLibProjectService libprojectService;
    private @NonNull QdesProjectEntryService projectentryService;

    /**
     * 题目库-列表查询
     * title=&search_type=all&new_sort=-top_order,-updated_dt
     *
     * @return
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "page", value = "页码"),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "rowsPerPage", value = "每页条数")
    })
    @ApiOperation(value = "题目库-列表查询", notes = "题目库-列表查询", httpMethod = "GET")
    @GetMapping("/")
    public XmResultJson<Object> projects(@ApiIgnore Page<QdesProjectEntry> page, @XmGet QuestionLibProjectParam param, HttpServletRequest request) {
        if (PageUtil.isPageQuery(request) && !StrUtil.equals("all", param.getSearchType())) {
            return XmResultJson.success(questionlibService.projects(page, param));
        }
        return XmResultJson.success(questionlibService.projectsSumary(param));
    }

    @ApiImplicitParams({
            @ApiImplicitParam(required = true, paramType = "path", dataTypeClass = String.class, name = "id", value = "id")
    })
    @ApiOperation(value = "查询单个项目详情", notes = "查询单个项目详情", httpMethod = "GET")
    @GetMapping("/{id:[a-fA-F0-9]{24}}")
    public XmResultJson<QdesProjectDetailVo> getProjectDetail(@PathVariable("id") String id) {
        return XmResultJson.success(projectService.getProjectDetail(id, SecurityContextHolder
                .getUserId(), SecurityContextHolder.getOrgId()));
    }

    @ApiOperation(value = "创建项目")
    @PostMapping("/")
    public XmResultJson<QdesProjectVo> createProject(@RequestBody @Validated ProjectCreateParam param) {
        param.setUserId(SecurityContextHolder.getUserId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        return XmResultJson.success(projectService.createProject(param));
    }

    @ApiOperation(value = "删除项目")
    @DeleteMapping("/")
    public XmResultJson<QdesProjectDeleteVo> deleteProject(@RequestBody @Validated ProjectDeleteParam param) {
        param.setUserId(SecurityContextHolder.getUserId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        return XmResultJson.success(projectService.deleteProject(param));
    }

    @ApiImplicitParams({
            @ApiImplicitParam(required = true, paramType = "path", dataTypeClass = String.class, name = "id", value = "id")
    })
    @ApiOperation(value = "完成项目")
    @PutMapping({"/{id:[a-fA-F0-9]{24}}/finish/"})
    public XmResultJson<?> finishProject(@RequestBody @Validated ProjectFinishParam param, @PathVariable String id) {
        param.setUserId(SecurityContextHolder.getUserId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        projectService.finishProject(param);
        return XmResultJson.success();
    }

    @ApiImplicitParams({
            @ApiImplicitParam(required = true, paramType = "path", dataTypeClass = String.class, name = "id", value = "id")
    })
    @ApiOperation(value = "项目答卷数量统计")
    @GetMapping({"/{id:[a-fA-F0-9]{24}}/respondent/num"})
    public XmResultJson<QdesProjectRespNumVo> projectRespNum(@PathVariable("id") String id) {
        log.info("Now to projectRespNum");
        QdesProjectRespNumVo projectRespNum = projectService.getProjectRespNum(id);
        //转换返回结构
        return XmResultJson.success(projectRespNum);
    }

    @ApiImplicitParams({
            @ApiImplicitParam(required = true, paramType = "path", dataTypeClass = String.class, name = "id", value = "id")
    })
    @ApiOperation(value = "修改项目标题")
    @PutMapping({"/{id:[a-fA-F0-9]{24}}/title"})
    public XmResultJson<Void> projectTitle(@PathVariable("id") String id, @RequestBody @Validated ProjectTitleParam param) {
        log.info("Now to projectTitle");
        //转换返回结构
        projectService.updateProjectTitle(id, param.getTitle());
        return XmResultJson.success();
    }

    @ApiImplicitParams({
            @ApiImplicitParam(required = true, paramType = "path", dataTypeClass = String.class, name = "id", value = "id")
    })
    @ApiOperation(value = "更新是否已读")
    @PutMapping({"/{id:[a-fA-F0-9]{24}}/read"})
    public XmResultJson<JSONObject> projectRead(@PathVariable("id") String id, @RequestBody @Validated ProjectReadParam param) {
        log.info("Now to projectRead");
        param.setUserId(SecurityContextHolder.getUserId());
        projectService.updateProjectRead(id, param);
        return XmResultJson.success(new JSONObject());
    }

    @ApiOperation(value = "修改项目所属文件夹")
    @PutMapping({"/{id:[a-fA-F0-9]{24}}/folder"})
    public XmResultJson<Void> projectFolder(@PathVariable("id") String id, @RequestBody @Validated ProjectFolderIdParam param) {
        log.info("Now to projectFolder");
        //转换返回结构
        param.setUserId(SecurityContextHolder.getUserId());
        projectService.updateProjectFolder(id, param);
        return XmResultJson.success();
    }

    @ApiOperation(value = "项目协助-获取项目的被分享人列表")
    @GetMapping({"/{id:[a-fA-F0-9]{24}}/share/users"})
    public XmResultJson<Map<String, List<QdesProjectentryVo>>> getShareUsers(@PathVariable("id") String id) {
        List<QdesProjectentryVo> list = projectentryService.getShareUsers(id);
        Map<String, List<QdesProjectentryVo>> data = new HashMap<>(2);
        data.put("data", list);
        return XmResultJson.success(data);
    }

    @ApiOperation(value = "项目协助-分享项目")
    @PostMapping({"/{id:[a-fA-F0-9]{24}}/share"})
    public XmResultJson<?> shareUsers(@PathVariable("id") String id, @RequestBody ShareUserParam shareUserParam) {
        return projectentryService.shareUsers(id, shareUserParam);
    }

    @ApiOperation(value = "拷贝项目")
    @PostMapping("/{id:[a-fA-F0-9]{24}}/copy")
    public XmResultJson<QdesProject> copyProject(@PathVariable("id") String id, @RequestBody @Validated ProjectCreateParam param) {
        param.setUserId(SecurityContextHolder.getUserId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        QdesProject ret = null;
        try {
            ret = libprojectService.copyProject(id, param);
        } catch (IOException e) {
            XmResultJson.fail(1, e.getLocalizedMessage());
        }
        return XmResultJson.success(ret);
    }

    @ApiOperation(value = "模板库-添加-获取可操作的项目列表")
    @GetMapping("/permission")
    public XmResultJson<?> getOperableProjectList(
            @RequestParam Integer permission, @RequestParam(required = false) Integer page,
            @RequestParam(required = false) Integer rowsPerPage,
            @RequestParam(required = false) String title,
            @RequestParam(required = false) Integer status) {
        return XmResultJson.handleServiceResult(libprojectService.getOperableProjectList(permission, page, rowsPerPage,
                title, status, SecurityContextHolder.getUserId()));
    }

    @ApiOperation(value = "设置项目为置顶,取消项目置顶")
    @PutMapping("/{id:[a-fA-F0-9]{24}}/top")
    public XmResultJson<Integer> projectTop(@PathVariable("id") String id, @RequestBody Map map) {
        Boolean setTop = (Boolean) map.get("set_top");
        if (Objects.isNull(setTop)) {
            return XmResultJson.fail(ReqErrorCodeConstants.PARAM_LOST, ":set_top is required");
        }
        return XmResultJson.success(libprojectService.projectTop(id, setTop, SecurityContextHolder.getUserId()));
    }

    @ApiImplicitParams({
            @ApiImplicitParam(required = true, paramType = "path", dataTypeClass = String.class, name = "id", value = "id")
    })
    @ApiOperation(value = "获取当前问卷的可设置配额的题目列表")
    @GetMapping({"/{id:[a-fA-F0-9]{24}}/questions"})
    public XmResultJson<List<JSONObject>> projectQuestions(@PathVariable("id") String id, @XmGet ProjectQuestionParam param) {
        log.info("Now to projectQuestions");
        List<JSONObject> questions = projectService.getProjectQuestions(id, param);
        //转换返回结构
        return XmResultJson.success(questions);
    }

    @ApiOperation(value = "导入项目")
    @PostMapping(value = "/import", consumes = MediaType.APPLICATION_JSON_VALUE)
    public XmResultJson<QdesImportProjectVo> importProjectByTxt(@RequestBody @Validated ProjectImportParam param) {
        param.setUserId(SecurityContextHolder.getUserId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        return projectService.importProject(param, null);
    }

    @ApiOperation(value = "导入项目")
    @PostMapping(value = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public XmResultJson<QdesImportProjectVo> importProjectByExcel(@RequestParam(value = "file", required = false) MultipartFile file,
                                                                  @RequestParam(value = "type", required = false) String type,
                                                                  @RequestParam(value = "data", required = false) JSONObject data) {

        ProjectImportParam param = new ProjectImportParam();
        param.setType(type);
        param.setData(data);
        param.setUserId(SecurityContextHolder.getUserId());
        param.setOrgId(SecurityContextHolder.getOrgId());
        return projectService.importProject(param, file);
    }

    @ApiOperation(value = "下载问卷模板", produces = "application/json", httpMethod = "GET")
    @GetMapping("/template")
    public void templateProject(HttpServletResponse response) throws IOException {
        projectService.templateProject(response);
    }

    @ApiOperation(value = "一键清除未读")
    @PutMapping("/readall")
    public XmResultJson<Void> readallProject() {
        projectService.readAllProject(SecurityContextHolder.getUserId(), SecurityContextHolder.getOrgId());
        return XmResultJson.success();
    }
}
